/**
 * 
 */
package com.rogers.rmcdouga.skirmishgadget.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.gen2.logging.shared.Log;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Event.NativePreviewEvent;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

/**
 * @author Rob McDougall
 *
 */
public class SetMapDialog extends DialogBox implements ImageURLBox.URLBox_ValidityCallback
{
	private static final String SET_MAP_BACKGOUND = "Set Map Backgound";

	private static SetMapDialogUiBinder uiBinder = GWT.create(SetMapDialogUiBinder.class);
	interface SetMapDialogUiBinder extends UiBinder<Widget, SetMapDialog> {	}

	interface DialogResult {
		void action(SetMapDialog dlg);
	}
	
	// State variables
	enum MapSize { CURRENT, IMAGE, CUSTOM };
	private MapSize customMapSize_state = MapSize.IMAGE;	// Has the user chosen to make the map size custom?
	
	// Member Variables
	private DialogResult okAction;
	private DialogResult cancelAction;
	private int originalMapWidth;
	private int originalMapHeight;
	
	@UiField
	ImageURLBox mapURLBox;

	@UiField
	Button okButton;

	@UiField
	Button cancelButton;
	
	@UiField
	TextBox mapWidth;
	
	@UiField
	TextBox mapHeight;
	
	@UiField
	RadioButton mapSize_CurrentSize;

	@UiField
	RadioButton mapSize_ImageSize;

	@UiField
	RadioButton mapSize_CustomSize;

	private void init()
	{
		setText(SET_MAP_BACKGOUND);
		setWidget(uiBinder.createAndBindUi(this));
		mapURLBox.setCallback(this);
	}

	private void init(String currentMapURL)
	{
		init();
		mapURLBox.setUrl(currentMapURL);
	}
	
	  public SetMapDialog() {
		super();
		init();
	}

	public SetMapDialog(boolean autoHide) {
		super(autoHide);
		init();
	}
		
	public SetMapDialog(boolean autoHide, boolean modal) {
		super(autoHide, modal);
		init();
	}

	public SetMapDialog(String currentMapURL) {
		super();
		init(currentMapURL);
	}
	
	public SetMapDialog(boolean autoHide, String currentMapURL) {
		super(autoHide);
		init(currentMapURL);
	}

	public SetMapDialog(boolean autoHide, boolean modal, String currentMapURL) {
		super(autoHide, modal);
		init(currentMapURL);
	}

	public DialogResult getOkAction()
	{
		return okAction;
	}

	public void setOkAction(DialogResult okAction)
	{
		this.okAction = okAction;
	}

	public DialogResult getCancelAction()
	{
		return cancelAction;
	}

	public void setCancelAction(DialogResult cancelAction)
	{
		this.cancelAction = cancelAction;
	}

	@Override
	protected void onPreviewNativeEvent(NativePreviewEvent preview)
	{
		super.onPreviewNativeEvent(preview);

		NativeEvent evt = preview.getNativeEvent();
		if (evt.getType().equals("keydown"))
		{
			// Use the popup's key preview hooks to close the dialog when either
			// enter or escape is pressed.
			switch (evt.getKeyCode()){
			case KeyCodes.KEY_ENTER:
				if (getOkAction() != null)
					getOkAction().action(this);
				hide();
				break;
			case KeyCodes.KEY_ESCAPE:
				if (getCancelAction() != null)
					getCancelAction().action(this);
				hide();
				break;
			}
		}
	}

	@UiHandler("okButton")
	void okButtonClick(ClickEvent e)
	{
		if (getOkAction() != null)
			getOkAction().action(this);
		hide();
	}
	
	@UiHandler("cancelButton")
	void cancelButtonClick(ClickEvent e)
	{
		if (getCancelAction() != null)
			getCancelAction().action(this);
		hide();
	}

	@UiHandler("mapSize_CurrentSize")
	void MapSize_CurrentSize_Click(ClickEvent e)
	{
		setCustomMapSize_state(MapSize.CURRENT);
	}

	@UiHandler("mapSize_ImageSize")
	void MapSize_ImageSize_Click(ClickEvent e)
	{
		setCustomMapSize_state(MapSize.IMAGE);
	}

	@UiHandler("mapSize_CustomSize")
	void MapSize_CustomSize_Click(ClickEvent e)
	{
		setCustomMapSize_state(MapSize.CUSTOM);
	}

	public MapSize getCustomMapSize_state()
	{
		return customMapSize_state;
	}

	public void setCustomMapSize_state(MapSize customMapSizeState)
	{
		customMapSize_state = customMapSizeState;
		enableAndDisableFields();
	}

	private void enableAndDisableFields()
	{
		if (!mapURLBox.isValidURL())
		{
			okButton.setEnabled(false);
			mapWidth.setEnabled(false);
			mapHeight.setEnabled(false);
			mapSize_ImageSize.setEnabled(false);
			mapSize_CustomSize.setEnabled(false);
		}
		else
		{
			okButton.setEnabled(true);
			mapSize_ImageSize.setEnabled(true);
			mapSize_CustomSize.setEnabled(true);
			switch(getCustomMapSize_state())
			{
			case CUSTOM:
				mapWidth.setEnabled(true);
				mapHeight.setEnabled(true);
				break;
			case CURRENT:
				mapWidth.setEnabled(false);
				mapHeight.setEnabled(false);
				mapWidth.setText(Integer.toString(originalMapWidth));
				mapHeight.setText(Integer.toString(originalMapHeight));
				break;
			case IMAGE:
				mapWidth.setEnabled(false);
				mapHeight.setEnabled(false);
				mapWidth.setText(Integer.toString(mapURLBox.getImage().getWidth()));
				mapHeight.setText(Integer.toString(mapURLBox.getImage().getHeight()));
				break;
			default:
				throw new IllegalArgumentException("Illegal CustomMapSize_state value: '" + getCustomMapSize_state().name() + ".value='" + getCustomMapSize_state().toString() + "'.");
			}
		}
	}

	@Override
	public void invalidURL()
	{
		Log.info("SetMapDialog invalidURL() entered.");
		enableAndDisableFields();
	}

	@Override
	public void validURL()
	{
		Log.info("SetMapDialog validURL() entered.");
		enableAndDisableFields();
	}

	public String getMapURL()
	{
		return mapURLBox.getUrl();
	}

	public int getMapWidth()
	{
		return Integer.parseInt(mapWidth.getText());
	}

	public int getMapHeight()
	{
		return Integer.parseInt(mapHeight.getText());
	}

	public void setOriginalMapWidth(int originalMapWidth)
	{
		this.originalMapWidth = originalMapWidth;
	}

	public void setOriginalMapHeight(int originalMapHeight)
	{
		this.originalMapHeight = originalMapHeight;
	}

	
}
